package com.mzj.saas.mservice.qiyuesuo.service;

import com.alibaba.fastjson.JSON;
import com.mzj.saas.mservice.qiyuesuo.vo.ContractDraftVO;
import com.mzj.saas.mservice.qiyuesuo.vo.DocumentFileVO;
import com.mzj.saas.mservice.qiyuesuo.vo.DocumentTemplateVO;
import com.mzj.saas.mservice.qiyuesuo.vo.ElectronicContractVO;
import com.qiyuesuo.sdk.v2.SdkClient;
import com.qiyuesuo.sdk.v2.bean.*;
import com.qiyuesuo.sdk.v2.http.StreamFile;
import com.qiyuesuo.sdk.v2.json.JSONUtils;
import com.qiyuesuo.sdk.v2.request.*;
import com.qiyuesuo.sdk.v2.response.ContractShorturlResult;
import com.qiyuesuo.sdk.v2.response.DocumentAddResult;
import com.qiyuesuo.sdk.v2.response.SdkResponse;
import com.qiyuesuo.sdk.v2.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;

/**
 * 契约锁接口-合同
 * 
 * @author hp
 *
 */
@Service
public class QiYueSuoContractService {

	private Logger logger = LoggerFactory.getLogger(QiYueSuoContractService.class);

	@Autowired
	private SdkClient sdkClient;

	/**
	 * 创建合同草稿 https://open.qiyuesuo.com/document?id=2657157684079370591
	 */
	public Contract createContractDraft(ContractDraftVO vo) {
		try {
			// 合同基本参数
			Contract contract = new Contract();
			contract.setSubject(vo.getSubject());
			contract.setCategory(new Category(vo.getCategoryId()));
			contract.setSend(false);
			contract.setTenantName(vo.getTenantName());
			contract.setCreator(new User(vo.getPartnerName(), vo.getPartnerContact(), vo.getPartnerContactType()));

			// 接受方
			Signatory signatory1 = new Signatory();
			signatory1.setTenantName(vo.getReceiverTenantName());
			signatory1.setTenantType(vo.getReceiverType());
			signatory1
					.setReceiver(new User(vo.getReceiverName(), vo.getReceiverContact(), vo.getReceiverContactType()));
			signatory1.setSerialNo(2);

			// 对接方
			Signatory signatory2 = new Signatory();
			signatory2.setTenantName(vo.getPartnerTenantName());
			signatory2.setTenantType(vo.getPartnerType());
			signatory2.setReceiver(new User(vo.getPartnerName(), vo.getPartnerContact(), vo.getPartnerContactType()));
			signatory2.setSerialNo(1);

			// 签署动作/签署流程
			Action action = new Action(vo.getActionType(), vo.getSerialNo());
			signatory2.addAction(action);

			// 设置签署方
			contract.addSignatory(signatory1);
			contract.addSignatory(signatory2);

			// 设置模板的参数
			if (!CollectionUtils.isEmpty(vo.getParams())) {
				vo.getParams().forEach(param -> {
					contract.addTemplateParam(param);
				});
			}
			logger.info("创建合同草稿, 请求参数={}", JSON.toJSONString(contract));
			// 创建合同
			ContractDraftRequest request = new ContractDraftRequest(contract);
			String response = sdkClient.service(request);
			SdkResponse<Contract> responseObj = JSONUtils.toQysResponse(response, Contract.class);
			// 返回结果
			if (responseObj.getCode() == 0) {
				Contract result = responseObj.getResult();
				logger.info("创建合同草稿成功，合同ID:{}", result.getId());
				return result;
			} else {
				logger.info("创建合同请求失败，错误码:{}，错误信息:{}", responseObj.getCode(), responseObj.getMessage());
			}
		} catch (Exception e) {
			logger.error("创建合同草稿异常" + e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 用模板添加合同文档 https://open.qiyuesuo.com/document?id=2740885975516320051
	 */
	public Long documentAddbytemplate(DocumentTemplateVO vo) {
		try {
			// 添加合同文档
			DocumentAddByTemplateRequest request = new DocumentAddByTemplateRequest(vo.getContractId(),
					vo.getTemplateId(), vo.getTemplateParams(), vo.getTitle());
			String response = sdkClient.service(request);
			SdkResponse<DocumentAddResult> responseObj = JSONUtils.toQysResponse(response, DocumentAddResult.class);
			if (responseObj.getCode() == 0) {
				DocumentAddResult result = responseObj.getResult();
				logger.info("用模板添加合同文档成功，文档ID:{}", result.getDocumentId());
				return result.getDocumentId();
			} else {
				logger.info("创建合同文档请求失败，错误码:{}，错误信息:{}", responseObj.getCode(), responseObj.getMessage());
			}
		} catch (Exception e) {
			logger.error("创建合同文档异常" + e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 用文件添加合同文档 https://open.qiyuesuo.com/document?id=2740885831488119670
	 */
	public Long documentAddbyfile(DocumentFileVO vo, String filePath) {
		try {
			InputStream inputStream = null;
			if (vo.getFile() == null) {
				inputStream = new FileInputStream(new File(filePath));
			} else {
				inputStream = vo.getFile().getInputStream();
			}
			DocumentAddByFileRequest request = new DocumentAddByFileRequest(Long.parseLong(vo.getContractId()),
					new StreamFile(inputStream), vo.getFileSuffix(), vo.getTitle());
			String response = sdkClient.service(request);
			SdkResponse<DocumentAddResult> responseObj = JSONUtils.toQysResponse(response, DocumentAddResult.class);
			if (responseObj.getCode() == 0) {
				DocumentAddResult result = responseObj.getResult();
				logger.info("用文件添加合同文档成功，文档ID:{}", result.getDocumentId());
				return result.getDocumentId();
			} else {
				logger.info("用文件添加合同文档请求失败，错误码:{}，错误信息:{}", responseObj.getCode(), responseObj.getMessage());
			}
		} catch (Exception e) {
			logger.error("用文件添加合同文档异常" + e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 合同详情
	 * 
	 * @param contractId
	 *            合同文档ID
	 *            https://open.qiyuesuo.com/document?id=2657159379555463201
	 * @return
	 */
	public Contract contractDetail(Long contractId) {
		try {
			ContractDetailRequest request = new ContractDetailRequest(contractId);
			String response = sdkClient.service(request);
			SdkResponse<Contract> responseObj = JSONUtils.toQysResponse(response, Contract.class);
			if (responseObj.getCode() == 0) {
				Contract contract = responseObj.getResult();
				logger.info("合同详情查询，合同主题：{}", contract.getSubject());
				return contract;
			} else {
				logger.info("请求失败，错误码:{}，错误信息:{}", responseObj.getCode(), responseObj.getMessage());
			}
		} catch (Exception e) {
			logger.error("用文件添加合同文档异常" + e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 下载合同文档 https://open.qiyuesuo.com/document?id=2657159732292231611
	 * 
	 * @param contractId
	 *            合同ID
	 */
	public File documentDownload(Long contractId) {
		try {
			DocumentDownloadRequest request = new DocumentDownloadRequest(contractId);
			File file = File.createTempFile("pattern", ".pdf");
			FileOutputStream fos = new FileOutputStream(file);
			sdkClient.download(request, fos);
			IOUtils.safeClose(fos);
			return file;
		} catch (Exception e) {
			logger.error("下载合同文档异常" + e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 获取合同的签署短链接。
	 * 
	 * @param contractId
	 *            合同ID
	 * @param tenantName
	 *            子公司名称
	 * @param contact
	 *            指定登陆账号，支持邮箱和手机联系方式
	 * @return
	 */
	public String contractShorturl(Long contractId, String tenantName, String contact) {
		ContractShorturlRequest request = new ContractShorturlRequest(contractId);
		if (StringUtils.isNotBlank(tenantName)) {
			request.setTenantName(tenantName);
		}
		if (StringUtils.isNotBlank(contact)) {
			request.setContact(contact);
		}
		String response = sdkClient.service(request);
		SdkResponse<ContractShorturlResult> responseObj = JSONUtils.toQysResponse(response,
				ContractShorturlResult.class);
		if (responseObj.getCode() == 0) {
			ContractShorturlResult result = responseObj.getResult();
			return result.getShorturl();
		} else {
			logger.info("请求失败，错误码:{}，错误信息:{}", responseObj.getCode(), responseObj.getMessage());
		}

		return null;
	}

	/**
	 * 指定签署位置并发起合同
	 * 
	 * @return
	 */
	public SdkResponse<Object> sendContract(ElectronicContractVO vo) {
		// 发起合同
		ContractSendRequest request = new ContractSendRequest(vo.getContractId(), vo.getStampers());
		if (StringUtils.isNotBlank(vo.getTenantName())) {
			request.setTenantName(vo.getTenantName());
		}
		request.setStamperRule(vo.getStamperRule());
		logger.info("Contract, contractSendRequest={}", JSON.toJSONString(request));
		String response = sdkClient.service(request);
		return JSONUtils.toQysResponse(response);
	}
}